#include "gui_draw_rgb565.h"
#include "sys_uart.h"
#include "gui_draw.h"
#include "font.h"
#include "math.h"

/*
LCD 清屏
*/
void GUI_Clear_RGB565(unsigned short Color)
{
	int i;
	for (i = 0; i < Canvas_len; i++)
	{
		Canvas_rgb565[i] = Color;
	}
}
/*
LCD 画点
*/
void GUI_Draw_Points_RGB565(int x, int y, unsigned short Color)
{
	Canvas_rgb565[y * Canvas_w + x] = Color;
}
/*
LCD 画线
fd=线宽
*/
void GUI_Draw_Line_RGB565(int x0, int y0, int x1, int y1, unsigned short color, int fd)
{
	u16 x, y;
	u16 dx; // = abs(x1 - x0);
	u16 dy; // = abs(y1 - y0);

	if (y0 == y1) // 平行线
	{
		if (x0 <= x1) // 确定左边第一个点
		{
			x = x0;
		}
		else
		{
			x = x1;
			x1 = x0;
		}
		while (x <= x1) // 确定点数
		{
			GUI_Draw_Rectangle_RGB565_X(x, y0, fd, fd, color); // 画指定颜色的点
			x++;											   // 指向下一个点
		}
		return;
	}
	////////////////////////////////////////////////////////////////////////////
	else if (y0 > y1) // 非平形线
	{
		dy = y0 - y1; // 得到垂直差值
	}
	else
	{
		dy = y1 - y0;
	}
	///////////////////////////////////////////////////////////////////////////
	if (x0 == x1) // 为垂直线
	{
		if (y0 <= y1) // 得到最左边第一个点
		{
			y = y0;
		}
		else
		{
			y = y1;
			y1 = y0;
		}
		while (y <= y1) // 确定点数
		{
			GUI_Draw_Rectangle_RGB565_X(x0, y, fd, fd, color);
			y++; // 确定下一个点
		}
		return;
	}
	///////////////////////////////////////////////////////////////////////////
	else if (x0 > x1) // 非垂直线，并确定方向
	{
		dx = x0 - x1; // 得到平行差值
		x = x1;		  // X1在左
		x1 = x0;	  // X0在右
		y = y1;		  // Y1在左
		y1 = y0;	  // Y0在右
	}
	else
	{
		dx = x1 - x0;
		x = x0; // X0在左
		y = y0; // Y0在左
	}

	if (dx == dy) // 差值相等为正斜线///////////////////////////////////////////////////////////////////
	{
		while (x <= x1) // 得到点数
		{
			x++;		// X值加
			if (y > y1) // Y确定方向在加减
			{
				y--;
			}
			else
			{
				y++;
			}
			GUI_Draw_Rectangle_RGB565_X(x, y, fd, fd, color); // 以X，Y画点
		}
	}
	/////////////////////////////////////////////////////////////////////////////////////非正斜线
	else
	{
		GUI_Draw_Rectangle_RGB565_X(x, y, fd, fd, color); // 画第一个点
		if (y < y1)										  // Y方向向下长，则
		{
			if (dx > dy) // 如果两X的距离大于两Y的距离，则	  (只计算90度的45度)
			{
				////////////////////////////以下是以斜率计算画点位置
				s16 p = dy * 2 - dx;
				s16 twoDy = 2 * dy;
				s16 twoDyMinusDx = 2 * (dy - dx);
				while (x < x1)
				{
					x++;
					if (p < 0)
					{
						p += twoDy; // 如P<0，P加一次,斜率增加一倍，Y值不变，X值加1。
					}
					else
					{
						y++;
						p += twoDyMinusDx; // 如P>0,回到初值
					}
					GUI_Draw_Rectangle_RGB565_X(x, y, fd, fd, color);
				}
			}
			else // 如果两Y的距离大于两X的距离，则		（计算90度的另一个45度）
			{
				s16 p = dx * 2 - dy;
				s16 twoDx = 2 * dx;
				s16 twoDxMinusDy = 2 * (dx - dy);
				while (y < y1)
				{
					y++;
					if (p < 0)
					{
						p += twoDx;
					}
					else
					{
						x++;
						p += twoDxMinusDy;
					}
					GUI_Draw_Rectangle_RGB565_X(x, y, fd, fd, color);
				}
			}
		}
		else //////////////////////////////////////////////////////////////////////Y方向向上增长
		{
			if (dx > dy)
			{
				s16 p = dy * 2 - dx;
				s16 twoDy = 2 * dy;
				s16 twoDyMinusDx = 2 * (dy - dx);
				while (x < x1)
				{
					x++;
					if (p < 0)
					{
						p += twoDy;
					}
					else
					{
						y--;
						p += twoDyMinusDx;
					}
					GUI_Draw_Rectangle_RGB565_X(x, y, fd, fd, color);
				}
			}
			else
			{
				s16 p = dx * 2 - dy;
				s16 twoDx = 2 * dx;
				s16 twoDxMinusDy = 2 * (dx - dy);
				while (y1 < y)
				{
					y--;
					if (p < 0)
					{
						p += twoDx;
					}
					else
					{
						x++;
						p += twoDxMinusDy;
					}
					GUI_Draw_Rectangle_RGB565_X(x, y, fd, fd, color);
				}
			}
		}
	}
}
/*
LCD 画圆
fill=0 不填充
fill=1 填充
line_w=不填充时的线宽
*/
void GUI_Draw_Circle_RGB565(int cx, int cy, int r, unsigned short color, int fill, int line_w)
{
	double n, x, y, m;
DRST:
	if (r == 0)
	{
		GUI_Draw_Points_RGB565(cx, cy, color);
		return;
	}
	else
	{
		for (m = 0; m < 360; m = m + 1)
		{
			n = 2 * 3.1415926 * (m / 360.0);
			x = r * cos(n) + cx;
			y = r * sin(n) + cy;
			GUI_Draw_Points_RGB565(x, y, color);
		}
	}
	if (fill == 1)
	{
		r--;
		if (r > 0)
		{
			goto DRST;
		}
	}
	else
	{
		line_w--;
		r--;
		if ((r > 0) && (line_w > 0))
		{
			goto DRST;
		}
	}
}

/*
LCD 画矩形
*/
void GUI_Draw_Rectangle_RGB565_X(int x, int y, int w, int h, unsigned short Color)
{
	int i, l;
	for (i = 0; i < h; i++)		// y
		for (l = 0; l < w; l++) // x
			Canvas_rgb565[(y + i) * Canvas_w + (x + l)] = Color;
}
/*
LCD 画矩形
fill=0 不填充
fill=1 填充
line_w=不填充时的线宽
*/
void GUI_Draw_Rectangle_RGB565(int x, int y, int w, int h, unsigned short Color, int fill, int line_w)
{
	if (fill == 0)
	{
		GUI_Draw_Rectangle_RGB565_X(x, y, line_w, h, Color);
		GUI_Draw_Rectangle_RGB565_X(x, y, w, line_w, Color);
		GUI_Draw_Rectangle_RGB565_X(x + w - line_w, y, line_w, h, Color);
		GUI_Draw_Rectangle_RGB565_X(x, y + h - line_w, w, line_w, Color);
	}
	else
	{
		GUI_Draw_Rectangle_RGB565_X(x, y, w, h, Color);
	}
}
/*
显示ASCII
fx =1反显
fd =放大倍数
*/
void GUI_Draw_ASCII_RGB565(int x, int y, int n, unsigned short Color1, unsigned short Color2, int fx, int fd)
{
	u8 i, l, d;
	u8 w = 8 * fd;
	u8 h = 16 * fd;

	for (i = 0; i < h; i += fd) // y
	{
		d = ASCII_1608[n - 0x20][i / fd];
		for (l = 0; l < w; l += fd) // x
		{
			if (d & 0x80)
				GUI_Draw_Rectangle_RGB565_X(x + l, y + i, fd, fd, Color1);
			else
			{
				if (fx == 1) // 反显
				{
					GUI_Draw_Rectangle_RGB565_X(x + l, y + i, fd, fd, Color2);
				}
			}
			d = d << 1;
		}
	}
}
/*
显示String
fx =1反显
fd =放大倍数
*/
void GUI_Draw_String_RGB565(int x, int y, char *str, unsigned short Color1, unsigned short Color2, int fx, int fd)
{
	while (*str != '\0')
	{
		GUI_Draw_ASCII_RGB565(x, y, *str, Color1, Color2, fx, fd);
		x += (8 * fd);
		if (x > (Canvas_w - (8 * fd)))
		{
			y++;
			x = 0;
		}
		str++;
	}
}

/*
显示16色位图片
*/
void GUI_Draw_Picture_RGB565(int x, int y, int w, int h, char *pic)
{
	int i, l, a, b;
	short *tpic = (short *)pic;
	for (i = 0; i < h; i++) // y
	{
		a = (y + i) * Canvas_w + x;
		b = w * i;
		for (l = 0; l < w; l++)
			Canvas_rgb565[a + l] = tpic[b + l];
	}
}

/*
读16色位显存
*/
void GUI_Read_Lcdbuff_RGB565(int x, int y, int w, int h, char *pic)
{
	int i, l, a, b;
	short *tpic = (short *)pic;
	for (i = 0; i < h; i++) // y
	{
		a = (y + i) * Canvas_w + x;
		b = w * i;
		for (l = 0; l < w; l++)
			tpic[b + l] = Canvas_rgb565[a + l];
	}
}

/*
显示汉字
fx =1反显
fd =放大倍数
*/
void GUI_Draw_HZ_RGB565(int x, int y, int v, unsigned short Color1, unsigned short Color2, int fx, int fd, char *hzprt)
{
	u8 i, l, s, d;
	u8 w = 8 * fd;
	u8 h = v * fd;
	u8 e = v / 8;
	if (fd <= 0)
	{
		sysprintf("ERR:fd<=0\r\n");
	}
	for (i = 0; i < h; i += fd) // y
	{
		for (s = 0; s < e; s++)
		{
			d = hzprt[(i * e) / fd + s];
			for (l = 0; l < w; l += fd) // x
			{
				if (d & 0x80)
					GUI_Draw_Rectangle_RGB565_X((s * w) + x + l, y + i, fd, fd, Color1);
				else
				{
					if (fx == 1) // 反显
					{
						GUI_Draw_Rectangle_RGB565_X((s * w) + x + l, y + i, fd, fd, Color2);
					}
				}
				d = d << 1;
			}
		}
	}
}
void GUI_Draw_HZ1616_RGB565(int x, int y, int n, unsigned short Color1, unsigned short Color2, int fx, int fd)
{
	GUI_Draw_HZ_RGB565(x, y, 16, Color1, Color2, fx, fd, (char *)HZ_1616[n]);
}
void GUI_Draw_HZ2424_RGB565(int x, int y, int n, unsigned short Color1, unsigned short Color2, int fx, int fd)
{
	GUI_Draw_HZ_RGB565(x, y, 24, Color1, Color2, fx, fd, (char *)HZ_2424[n]);
}
void GUI_Draw_HZ3232_RGB565(int x, int y, int n, unsigned short Color1, unsigned short Color2, int fx, int fd)
{
	GUI_Draw_HZ_RGB565(x, y, 32, Color1, Color2, fx, fd, (char *)HZ_3232[n]);
}
void GUI_Draw_HZ4040_RGB565(int x, int y, int n, unsigned short Color1, unsigned short Color2, int fx, int fd)
{
	GUI_Draw_HZ_RGB565(x, y, 40, Color1, Color2, fx, fd, (char *)HZ_4040[n]);
}
void GUI_Draw_HZ4848_RGB565(int x, int y, int n, unsigned short Color1, unsigned short Color2, int fx, int fd)
{
	GUI_Draw_HZ_RGB565(x, y, 48, Color1, Color2, fx, fd, (char *)HZ_4848[n]);
}
